﻿#include "HolidayUtil.h"
#include "Holiday.h"
//#include <optional>
#include <vector>
#include <sstream>
#include <iomanip>
#include <algorithm>

const std::vector<std::string>  HolidayUtil::NAMES = { "元旦节", "春节", "清明节", "劳动节", "端午节", "中秋节", "国庆节", "国庆中秋", "抗战胜利日" };

const int HolidayUtil::SIZE = 18;

const char HolidayUtil::ZERO = '0';

const std::string HolidayUtil::TAG_REMOVE = "~";


const std::string HolidayUtil::DATA =
"200112290020020101200112300020020101200201010120020101200201020120020101200201030120020101200202091020020212200202101020020212200202121120020212200202131120020212200202141120020212200202151120020212200202161120020212200202171120020212200202181120020212200204273020020501200204283020020501200205013120020501200205023120020501200205033120020501200205043120020501200205053120020501200205063120020501200205073120020501200209286020021001200209296020021001200210016120021001200210026120021001200210036120021001200210046120021001200210056120021001200210066120021001200210076120021001200301010120030101200302011120030201200302021120030201200302031120030201200302041120030201200302051120030201200302061120030201200302071120030201200302081020030201200302091020030201200304263020030501200304273020030501200305013120030501200305023120030501200305033120030501200305043120030501200305053120030501200305063120030501200305073120030501200309276020031001200309286020031001200310016120031001200310026120031001200310036120031001200310046120031001200310056120031001200310066120031001200310076120031001200401010120040101200401171020040122200401181020040122200401221120040122200401231120040122200401241120040122200401251120040122200401261120040122200401271120040122200401281120040122200405013120040501200405023120040501200405033120040501200405043120040501200405053120040501200405063120040501200405073120040501200405083020040501200405093020040501200410016120041001200410026120041001200410036120041001200410046120041001200410056120041001200410066120041001200410076120041001200410096020041001200410106020041001200501010120050101200501020120050101200501030120050101200502051020050209200502061020050209200502091120050209200502101120050209200502111120050209200502121120050209200502131120050209200502141120050209200502151120050209200504303020050501200505013120050501200505023120050501200505033120050501200505043120050501200505053120050501200505063120050501200505073120050501200505083020050501200510016120051001200510026120051001200510036120051001200510046120051001200510056120051001200510066120051001200510076120051001200510086020051001200510096020051001200512310020060101200601010120060101200601020120060101200601030120060101200601281020060129200601291120060129200601301120060129200601311120060129200602011120060129"
"20060202112006012920060203112006012920060204112006012920060205102006012920060429302006050120060430302006050120060501312006050120060502312006050120060503312006050120060504312006050120060505312006050120060506312006050120060507312006050120060930602006100120061001612006100120061002612006100120061003612006100120061004612006100120061005612006100120061006612006100120061007612006100120061008602006100120061230002007010120061231002007010120070101012007010120070102012007010120070103012007010120070217102007021820070218112007021820070219112007021820070220112007021820070221112007021820070222112007021820070223112007021820070224112007021820070225102007021820070428302007050120070429302007050120070501312007050120070502312007050120070503312007050120070504312007050120070505312007050120070506312007050120070507312007050120070929602007100120070930602007100120071001612007100120071002612007100120071003612007100120071004612007100120071005612007100120071006612007100120071007612007100120071229002008010120071230012008010120071231012008010120080101012008010120080202102008020620080203102008020620080206112008020620080207112008020620080208112008020620080209112008020620080210112008020620080211112008020620080212112008020620080404212008040420080405212008040420080406212008040420080501312008050120080502312008050120080503312008050120080504302008050120080607412008060820080608412008060820080609412008060820080913512008091420080914512008091420080915512008091420080927602008100120080928602008100120080929612008100120080930612008100120081001612008100120081002612008100120081003612008100120081004612008100120081005612008100120090101012009010120090102012009010120090103012009010120090104002009010120090124102009012520090125112009012520090126112009012520090127112009012520090128112009012520090129112009012520090130112009012520090131112009012520090201102009012520090404212009040420090405212009040420090406212009040420090501312009050120090502312009050120090503312009050120090528412009052820090529412009052820090530412009052820090531402009052820090927602009100120091001612009100120091002612009100120091003612009100120091004612009100120091005512009100320091006512009100320091007512009100320091008512009100320091010502009100320100101012010010120100102012010010120100103012010010120100213112010021320100214112010021320100215112010021320100216112010021320"
"10021711201002132010021811201002132010021911201002132010022010201002132010022110201002132010040321201004052010040421201004052010040521201004052010050131201005012010050231201005012010050331201005012010061240201006162010061340201006162010061441201006162010061541201006162010061641201006162010091950201009222010092251201009222010092351201009222010092451201009222010092550201009222010092660201010012010100161201010012010100261201010012010100361201010012010100461201010012010100561201010012010100661201010012010100761201010012010100960201010012011010101201101012011010201201101012011010301201101012011013010201102032011020211201102032011020311201102032011020411201102032011020511201102032011020611201102032011020711201102032011020811201102032011021210201102032011040220201104052011040321201104052011040421201104052011040521201104052011043031201105012011050131201105012011050231201105012011060441201106062011060541201106062011060641201106062011091051201109122011091151201109122011091251201109122011100161201110012011100261201110012011100361201110012011100461201110012011100561201110012011100661201110012011100761201110012011100860201110012011100960201110012011123100201201012012010101201201012012010201201201012012010301201201012012012110201201232012012211201201232012012311201201232012012411201201232012012511201201232012012611201201232012012711201201232012012811201201232012012910201201232012033120201204042012040120201204042012040221201204042012040321201204042012040421201204042012042830201205012012042931201205012012043031201205012012050131201205012012050230201205012012062241201206232012062341201206232012062441201206232012092950201209302012093051201209302012100161201210012012100261201210012012100361201210012012100461201210012012100561201210012012100661201210012012100761201210012012100860201210012013010101201301012013010201201301012013010301201301012013010500201301012013010600201301012013020911201302102013021011201302102013021111201302102013021211201302102013021311201302102013021411201302102013021511201302102013021610201302102013021710201302102013040421201304042013040521201304042013040621201304042013042730201305012013042830201305012013042931201305012013043031201305012013050131201305012013060840201306122013060940201306122013061041201306122013061141201306122013061241201306122013091951201309192013092051201309192013"
"09215120130919201309225020130919201309296020131001201310016120131001201310026120131001201310036120131001201310046120131001201310056120131001201310066120131001201310076120131001201401010120140101201401261020140131201401311120140131201402011120140131201402021120140131201402031120140131201402041120140131201402051120140131201402061120140131201402081020140131201404052120140405201404062120140405201404072120140405201405013120140501201405023120140501201405033120140501201405043020140501201405314120140602201406014120140602201406024120140602201409065120140908201409075120140908201409085120140908201409286020141001201410016120141001201410026120141001201410036120141001201410046120141004201410056120141001201410066120141001201410076120141001201410116020141001201501010120150101201501020120150101201501030120150101201501040020150101201502151020150219201502181120150219201502191120150219201502201120150219201502211120150219201502221120150219201502231120150219201502241120150219201502281020150219201504042120150405201504052120150405201504062120150405201505013120150501201505023120150501201505033120150501201506204120150620201506214120150620201506224120150620201509038120150903201509048120150903201509058120150903201509068020150903201509265120150927201509275120150927201510016120151001201510026120151001201510036120151001201510046120151004201510056120151001201510066120151001201510076120151001201510106020151001201601010120160101201601020120160101201601030120160101201602061020160208201602071120160208201602081120160208201602091120160208201602101120160208201602111120160208201602121120160208201602131120160208201602141020160208201604022120160404201604032120160404201604042120160404201604303120160501201605013120160501201605023120160501201606094120160609201606104120160609201606114120160609201606124020160609201609155120160915201609165120160915201609175120160915201609185020160915201610016120161001201610026120161001201610036120161001201610046120161001201610056120161001201610066120161001201610076120161001201610086020161001201610096020161001201612310120170101201701010120170101201701020120170101201701221020170128201701271120170128201701281120170128201701291120170128201701301120170128201701311120170128201702011120170128201702021120170128201702041020170128201704012020170404201704022120170404201704032120170404201704042120170404201704"
"29312017050120170430312017050120170501312017050120170527402017053020170528412017053020170529412017053020170530412017053020170930602017100120171001612017100120171002612017100120171003612017100120171004512017100420171005612017100120171006612017100120171007612017100120171008612017100120171230012018010120171231012018010120180101012018010120180211102018021620180215112018021620180216112018021620180217112018021620180218112018021620180219112018021620180220112018021620180221112018021620180224102018021620180405212018040520180406212018040520180407212018040520180408202018040520180428302018050120180429312018050120180430312018050120180501312018050120180616412018061820180617412018061820180618412018061820180922512018092420180923512018092420180924512018092420180929602018100120180930602018100120181001612018100120181002612018100120181003612018100120181004612018100120181005612018100120181006612018100120181007612018100120181229002019010120181230012019010120181231012019010120190101012019010120190202102019020520190203102019020520190204112019020520190205112019020520190206112019020520190207112019020520190208112019020520190209112019020520190210112019020520190405212019040520190406212019040520190407212019040520190428302019050120190501312019050120190502312019050120190503312019050120190504312019050120190505302019050120190607412019060720190608412019060720190609412019060720190913512019091320190914512019091320190915512019091320190929602019100120191001612019100120191002612019100120191003612019100120191004612019100120191005612019100120191006612019100120191007612019100120191012602019100120200101012020010120200119102020012520200124112020012520200125112020012520200126112020012520200127112020012520200128112020012520200129112020012520200130112020012520200131112020012520200201112020012520200202112020012520200404212020040420200405212020040420200406212020040420200426302020050120200501312020050120200502312020050120200503312020050120200504312020050120200505312020050120200509302020050120200625412020062520200626412020062520200627412020062520200628402020062520200927702020100120201001712020100120201002612020100120201003612020100120201004612020100120201005612020100120201006612020100120201007612020100120201008612020100120201010602020100120210101012021010120210102012021010120210103012021010120210207102021021220210211112021021220210212"
"11202102122021021311202102122021021411202102122021021511202102122021021611202102122021021711202102122021022010202102122021040321202104042021040421202104042021040521202104042021042530202105012021050131202105012021050231202105012021050331202105012021050431202105012021050531202105012021050830202105012021061241202106142021061341202106142021061441202106142021091850202109212021091951202109212021092051202109212021092151202109212021092660202110012021100161202110012021100261202110012021100361202110012021100461202110012021100561202110012021100661202110012021100761202110012021100960202110012022010101202201012022010201202201012022010301202201012022012910202202012022013010202202012022013111202202012022020111202202012022020211202202012022020311202202012022020411202202012022020511202202012022020611202202012022040220202204052022040321202204052022040421202204052022040521202204052022042430202205012022043031202205012022050131202205012022050231202205012022050331202205012022050431202205012022050730202205012022060341202206032022060441202206032022060541202206032022091051202209102022091151202209102022091251202209102022100161202210012022100261202210012022100361202210012022100461202210012022100561202210012022100661202210012022100761202210012022100860202210012022100960202210012022123101202301012023010101202301012023010201202301012023012111202301222023012211202301222023012311202301222023012411202301222023012511202301222023012611202301222023012711202301222023012810202301222023012910202301222023040521202304052023042330202305012023042931202305012023043031202305012023050131202305012023050231202305012023050331202305012023050630202305012023062241202306222023062341202306222023062441202306222023062540202306222023092951202309292023093061202310012023100161202310012023100261202310012023100361202310012023100461202310012023100561202310012023100661202310012023100760202310012023100860202310012023123001202401012023123101202401012024010101202401012024020410202402102024021011202402102024021111202402102024021211202402102024021311202402102024021411202402102024021511202402102024021611202402102024021711202402102024021810202402102024040421202404042024040521202404042024040621202404042024040720202404042024042830202405012024050131202405012024050231202405012024050331202405012024050431202405012024050531202405012024051130202405012024060841"
"20240610202406094120240610202406104120240610202409145020240917202409155120240917202409165120240917202409175120240917202409296020241001202410016120241001202410026120241001202410036120241001202410046120241001202410056120241001202410066120241001202410076120241001202410126020241001202501010120250101202501261020250129202501281120250129202501291120250129202501301120250129202501311120250129202502011120250129202502021120250129202502031120250129202502041120250129202502081020250129202504042120250404202504052120250404202504062120250404202504273020250501202505013120250501202505023120250501202505033120250501202505043120250501202505053120250501202505314120250531202506014120250531202506024120250531202509287020251001202510017120251001202510027120251001202510037120251001202510047120251001202510057120251001202510067120251001202510077120251001202510087120251001202510117020251001";


std::vector<std::string> HolidayUtil::NAMES_IN_USE = NAMES;

/// <summary>
/// 使用的节假日数据
/// </summary>
std::string HolidayUtil::DATA_IN_USE = DATA;


Holiday* HolidayUtil::BuildHolidayForward(std::string s)
{
	// 提取日期部分 (前8字符)
	std::string day = s.substr(0, 8);

	// 提取名称和工作标志字符
	char nameChar = s[8];      // 名称索引字符
	char workChar = s[9];      // 工作标志字符

	// 字符转索引并获取名称
	int nameIndex = nameChar - ZERO;
	std::string name = (nameIndex >= 0 && nameIndex < NAMES_IN_USE.size())
		? NAMES_IN_USE[nameIndex]
		: "Unknown";

		// 判断是否为工作日
		bool work = (workChar == ZERO);

		// 提取目标日期 (后8字符)
		std::string target = s.substr(10, 8);

		return new Holiday(day, name, work, target);
}

Holiday* HolidayUtil::BuildHolidayBackward(std::string s)
{
	// 获取字符串长度
	size_t size = s.length();

	// 边界检查（防止越界访问）
	if (size < 18) {
		// 处理错误：返回默认值或抛出异常
		return new Holiday("", "Invalid", false, "");
	}

	// 提取关键字符（倒数第10位开始取2个字符）
	char nameChar = s[size - 10];  // 相当于 chars[0]
	char workChar = s[size - 9];   // 相当于 chars[1]

	// 提取日期（倒数第18位开始取8字符）
	std::string day = s.substr(size - 18, 8);

	// 名称转换（带安全校验）
	int nameIndex = nameChar - ZERO;
	std::string name = (nameIndex >= 0 && nameIndex < NAMES_IN_USE.size())
		? NAMES_IN_USE[nameIndex]
		: "Unknown";

		// 工作标志判断
		bool work = (workChar == ZERO);

		// 提取目标日期（最后8字符）
		std::string target = s.substr(size - 8);

		return new Holiday(day, name, work, target);
}


std::string HolidayUtil::FindForward(const std::string& key)
{
	const int SIZE = key.size();
	size_t start = DATA_IN_USE.find(key);

	// 未找到 key 时返回空字符串
	if (start == std::string::npos) {
		return "";
	}
	// 截取从 start 到末尾的子串[9,11](@ref)
	std::string right = DATA_IN_USE.substr(start);

	// 对齐处理：截掉右侧非整数倍的部分
	size_t n = right.size() % SIZE;
	if (n > 0) {
		right = right.substr(n); // 移除前 n 个字符[10](@ref)
	}
	// 循环检查开头并逐步截断[12](@ref)
	while (!right.empty() &&
		right.size() >= static_cast<size_t>(SIZE) &&
		right.compare(0, SIZE, key) != 0) { // 检查是否以 key 开头[12](@ref)
		right = right.substr(SIZE); // 每次移除 SIZE 长度[9](@ref)
	}

	return right;
}

std::string HolidayUtil::FindBackward(const std::string& key)
{
	// 假设 DATA_IN_USE 是全局 std::string，SIZE 是块大小常量
	const int SIZE = key.size(); // 或根据实际定义调整

	// 从后向前查找 key（等效 LastIndexOf）
	size_t start = DATA_IN_USE.rfind(key);
	if (start == std::string::npos) {
		return ""; // 未找到返回空字符串
	}

	// 截取开头到 start+key.length() 的内容
	std::string left = DATA_IN_USE.substr(0, start + key.length());

	// 对齐处理：移除末尾非整数倍部分
	size_t n = left.length() % SIZE;
	if (n > 0) {
		left = left.substr(0, left.length() - n); // 移除末尾 n 个字符
	}

	// 循环检查结尾并逐步截断
	while (!left.empty() &&
		left.length() >= static_cast<size_t>(SIZE) &&
		left.substr(left.length() - key.length()) != key) { // 检查是否以 key 结尾
		left = left.substr(0, left.length() - SIZE); // 移除末尾 SIZE 长度
	}

	return left;
}

std::vector<Holiday> HolidayUtil::FindHolidaysForward(std::string key)
{
	std::vector<Holiday> holidays;  // C++ 中等效于 List<Holiday>
	std::string s = FindForward(key);  // 调用已转换的 FindForward 函数

	if (s.empty()) {  // C++ 中空字符串判断替代 null
		return holidays;
	}

	const size_t keySize = key.size();
	while (s.size() >= keySize && s.substr(0, keySize) == key) {
		holidays.push_back(*BuildHolidayForward(s));  // 添加对象到 vector
		s = s.substr(SIZE);  // 移动 SIZE 个字符
	}

	return holidays;
}

std::vector<Holiday>HolidayUtil::FindHolidaysBackward(std::string key)
{

	std::vector<Holiday> holidays; // 等效 C# 的 List<Holiday>
	std::string s = FindBackward(key); // 调用逆向查找函数

	// 检查空字符串（C++ 中替代 null 判断）
	if (s.empty()) {
		return holidays;
	}

	const size_t keySize = key.size();

	// 循环检查字符串是否以 key 结尾
	while (s.size() >= keySize &&
		s.substr(s.size() - keySize) == key) // 检查是否以 key 结尾
	{
		// 构建假日对象并添加到向量
		holidays.push_back(*BuildHolidayBackward(s));

		// 截断末尾的 SIZE 长度
		if (s.size() > SIZE) {
			s = s.substr(0, s.size() - SIZE);
		}
		else {
			break; // 防止空字符串操作
		}
	}

	// 反转结果向量（保持原始顺序）
	std::reverse(holidays.begin(), holidays.end());

	return holidays;

}

Holiday* HolidayUtil::GetHoliday(int year, int month, int day)
{
	// 格式化为两位字符串（不足补零）
	std::ostringstream monthStream, dayStream;
	monthStream << std::setw(2) << std::setfill('0') << month;
	dayStream << std::setw(2) << std::setfill('0') << day;

	// 拼接日期键（格式：YYYYMMDD）
	std::string key = std::to_string(year) + monthStream.str() + dayStream.str();

	// 查找匹配的假日列表
	std::vector<Holiday> holidays = FindHolidaysForward(key);

	// 返回首个假日或空值
	return holidays.empty() ? nullptr : &holidays.front();
}



Holiday* HolidayUtil::GetHoliday(std::string ymd)
{
	std::string formattedYmd = ymd;
	// 移除所有短横线
	auto last = std::remove(formattedYmd.begin(), formattedYmd.end(), '-');
	formattedYmd.erase(last, formattedYmd.end());

	// 移除其他非数字字符（可选增强）
	last = std::remove_if(formattedYmd.begin(), formattedYmd.end(),
		[](char c) { return !std::isdigit(c); });
	formattedYmd.erase(last, formattedYmd.end());

	auto holidays = FindHolidaysForward(formattedYmd);
	return holidays.empty() ? nullptr : &holidays[0];
}

std::vector<Holiday> HolidayUtil::GetHolidays(int year, int month)
{
	// 格式化为两位月份字符串（不足补零）
	std::ostringstream monthStream;
	monthStream << std::setw(2) << std::setfill('0') << month;

	// 拼接日期键（格式：YYYYMM）
	std::string key = std::to_string(year) + monthStream.str();

	// 查找匹配的假日列表
	return FindHolidaysForward(key);
}


std::vector<Holiday> HolidayUtil::GetHolidays(int year)
{
	return FindHolidaysForward(std::to_string(year));
}

std::vector<Holiday>HolidayUtil::GetHolidays(std::string ymd)
{
	// 创建处理用的字符串副本
	std::string cleanedYmd = ymd;

	// 移除所有短横线（修复图片中的 std::optional 错误）
	auto last = std::remove(cleanedYmd.begin(), cleanedYmd.end(), '-');
	cleanedYmd.erase(last, cleanedYmd.end());

	// 直接返回查找结果（避免使用 std::optional）
	return FindHolidaysForward(cleanedYmd);
}


std::vector<Holiday>HolidayUtil::GetHolidaysByTarget(std::string ymd)
{
	// 移除所有短横线（符合图片中显示的错误修复方法）
	std::string cleanedYmd = ymd;
	cleanedYmd.erase(
		std::remove(cleanedYmd.begin(), cleanedYmd.end(), '-'),
		cleanedYmd.end()
	);

	// 直接返回逆向查找结果（避免图片中的 std::nullopt 错误）
	return FindHolidaysBackward(cleanedYmd);
}

std::vector<Holiday> HolidayUtil::GetHolidaysByTarget(int year, int month, int day)
{
	// 使用字符串流格式化月份和日期（自动补零）[7,9](@ref)
	std::ostringstream monthStream, dayStream;
	monthStream << std::setw(2) << std::setfill('0') << month;
	dayStream << std::setw(2) << std::setfill('0') << day;

	// 拼接日期键（格式：YYYYMMDD）
	std::string key = std::to_string(year) + monthStream.str() + dayStream.str();

	// 返回逆向查找结果
	return FindHolidaysBackward(key);
}

void HolidayUtil::Fix(std::vector<std::string>* names, std::string* data)
{
	// 更新名称列表
	if (names != nullptr) {
		NAMES_IN_USE = *names;
	}

	// 空数据检查
	if (data == nullptr || data->empty()) {
		return;
	}

	std::string processingData = *data;
	std::string appendStr;

	// 分段处理数据
	while (processingData.length() >= SIZE) {
		std::string segment = processingData.substr(0, SIZE);
		std::string day = segment.substr(0, 8);
		bool remove = (segment[8] == TAG_REMOVE[0]);

		// 获取节假日信息
		Holiday* holiday = GetHoliday(day);

		if (holiday == nullptr) {
			if (!remove) {
				appendStr += segment; // 直接拼接字符串
			}
		}
		else {
			// 在名称列表中查找索引
			int nameIndex = -1;
			for (size_t i = 0; i < NAMES_IN_USE.size(); ++i) {
				if (NAMES_IN_USE[i] == holiday->Name) {
					nameIndex = static_cast<int>(i);
					break;
				}
			}

			if (nameIndex > -1) {
				// 构建旧键
				std::string oldKey = day
					+ static_cast<char>(nameIndex + ZERO)
					+ (holiday->Work ? ZERO : '1');

				// 移除目标中的短横线
				std::string targetClean = holiday->Target;
				targetClean.erase(std::remove(targetClean.begin(), targetClean.end(), '-'), targetClean.end());
				oldKey += targetClean;

				// 执行全局替换
				size_t pos = 0;
				while ((pos = DATA_IN_USE.find(oldKey, pos)) != std::string::npos) {
					DATA_IN_USE.replace(pos, oldKey.length(), remove ? "" : segment);
					pos += (remove ? 0 : segment.length()); // 调整位置
				}
			}
		}

		// 移动到下一段
		processingData = processingData.substr(SIZE);
	}

	// 追加剩余数据
	if (!appendStr.empty()) {
		DATA_IN_USE += appendStr;
	}
}


void  HolidayUtil::Fix(std::string data)
{
	Fix(nullptr, &data);
}
